/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved.
 * secGear is licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include <stdio.h>
#include <iostream>
#include <unistd.h>
#include <linux/limits.h>
#include "enclave.h"
#include "nested_u.h"
#include "string.h"
using namespace std;

#define BUF_LEN 32

void print_res(double result_)
{
    cout << result_ << endl;
}

void print_error()
{
    cout << "error" << endl;
}

void print_create()
{
    cout << "create subenclave success" << endl;
}

void print_destroy()
{
    cout << "destroy subenclave success" << endl;
}

void getid(int* id)
{
    cin >> id[0];
}


void print_send()
{
    cout << "Send Success!" << endl;
}

void print_recieve()
{
    cout << "Recieve Success!" << endl;
}

void print_send_hit()
{
    cout << "Please enter the subEnclaveID of the recipient:";
}

void print_recieve_hit()
{
    cout << "Please enter the subEnclaveID of the Sender:";
}

void print_reenter_hit()
{
    cout << "The subEnclaveID was not found,please re-enter:";
}

int main()
{
    int  retval = 0;
    char *path = PATH;
    char buf[BUF_LEN];
    cc_enclave_t context = {};
    cc_enclave_result_t res = CC_FAIL;

    char real_p[PATH_MAX];
    /* check file exists, if not exist then use absolute path */
    if (realpath(path, real_p) == NULL) {
        if (getcwd(real_p, sizeof(real_p)) == NULL) {
            printf("Cannot find enclave.sign.so");
            goto end;
        }
        if (PATH_MAX - strlen(real_p) <= strlen("/enclave.signed.so")) {
            printf("Failed to strcat enclave.sign.so path");
            goto end;
        }
        (void)strcat(real_p, "/enclave.signed.so");
    }

    res = cc_enclave_create(real_p, AUTO_ENCLAVE_TYPE, 0, SECGEAR_DEBUG_FLAG, NULL, 0, &context);
    if (res != CC_SUCCESS) {
        printf("host create enclave error\n");
        goto end; 
    }
    printf("host create enclave success\n");

    /*
    res = get_string(&context, &retval, buf);
    if (res != CC_SUCCESS || retval != (int)CC_SUCCESS) {
        printf("Ecall enclave error\n");
    } else {
        printf("enclave say:%s\n", buf);
    }
    */

    int num;
    cout << "Please enter the number of subEnclaves: ";
    cin >> num;
    double result_[2];
    //cin >> ID;
    
    //res = compute();
    //cout << result_[0];
    for (int i = 0;i < num;i++) {
        res = createSubEnclave(&context, &retval, i);
    }

    int sub, ID, op;
	while (1) {
		sub = -1;
		cout << "Please enter the subEnclaveID you want to operate: ";
		cin >> ID;
        //判断存在
		for (int i = 0; i < num; i++) {
			if (ID == i) {
				sub = i;
				break;
			}
		}
		if (sub == -1) {
			cout << "The subEnclaveID was not found,please re-enter!" << endl;
			continue;
		}

		cout << "Please enter the function you want:" << endl;
		cout << "1.ADD	2.SUB	3.MUL	4.DIV	5.EXP" << endl;
		cout << "6.SEND 7.RECV  8.SKIP	9.EXIT" << endl;
        
		cin >> op;

		if (op == 8)
			continue;
		if (op == 9)
			break;

		res = compute(&context, &retval,op, num, sub, result_);
	}

    for (int i = 0;i < num;i++) {
        res = destroySubEnclave(&context, &retval);
    }



    res = cc_enclave_destroy(&context);
    if(res != CC_SUCCESS) {
        printf("host destroy enclave error\n");
    } else {
        printf("host destroy enclave success\n");
    }
end:
    return res;
}
